package com.zlcx.tz.live.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zlcx.tz.live.client.UserClient;
import com.zlcx.tz.live.client.UserFriendClient;
import com.zlcx.tz.live.client.vo.UserFriendVO;
import com.zlcx.tz.live.constant.RedisKeyConst;
import com.zlcx.tz.live.constant.ResultStatus;
import com.zlcx.tz.live.exception.CheckRunException;
import com.zlcx.tz.live.utils.SignUtil;
import com.zlcx.tz.live.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.zlcx.tz.live.common.config.RedisConfig.CacheKeys.USER_TOTAL_LIVE_TIME;

/**
 * <p></p>
 * <PRE>
 * <BR>    修改记录
 * <BR>-----------------------------------------------
 * <BR>    修改日期         修改人          修改内容
 * </PRE>
 *
 * @author zl
 * @version 1.0
 * @date Created in 2019/4/18 11:40
 * @copyright: Copyright (c) founders
 */
@Service
@Slf4j
public class UserService {


    @Autowired
    UserClient userClient;

    @Value("${shangde.sign.secret}")
    String secret;

    @Autowired
    UserFriendClient userFriendClient;

    private Logger traceLoger = LoggerFactory.getLogger("traceloger");

    @Autowired
    RedisTemplate redisTemplate;

    public UserVO getUserInfo(Long userId){
        UserVO info = null;

        String key = RedisKeyConst.getUserInfoKey(userId);

        try {
            info = (UserVO) redisTemplate.opsForValue().get(key);
        }catch (Exception e){
            log.error("redis get error,key={},e={}", key, e);
        }
        if(info!=null){
            return info;
        }

        ResultVO<UserVO> resultVO =null;
        try {
            long t1 = System.currentTimeMillis();

            Map<String, String[]> requestParams = new HashMap<>(1);
            String sig = SignUtil.sign(secret, requestParams);
            resultVO = userClient.getUserInfo(userId);
            long t2 = System.currentTimeMillis();
            log.debug("查询用户信息cost:{}ms，sig={},userId={},resultVO={}",t2-t1,sig,userId, JSON.toJSONString(resultVO));
            if(resultVO==null || resultVO.getCode()==null || ResultStatus.SUCCESS.getCode()!=resultVO.getCode() || resultVO.getData()==null){
                log.error("查询用户信息失败，cost:{}ms，sig={},userId={},resultVO={}",t2-t1,sig,userId, JSON.toJSONString(resultVO));
                throw new CheckRunException("查询用户信息失败：userId="+userId);
            }
            info = resultVO.getData();
        } catch (Exception e) {
            log.error("查询用户信息失败，userId={},resultVO={},e={}",userId, JSON.toJSONString(resultVO),e);
        }

        if(info!=null){
            try {
                redisTemplate.opsForValue().set(key,info,1, TimeUnit.MINUTES);
            }catch (Exception e){
                log.error("redis set error,key={},e={}",key,e);
            }
        }

        return info;
    }


    public List<UserFriendVO> userFriendsList(Long userId){
        ResultVO resultVO =null;
        List<UserFriendVO> list = Lists.newArrayList();
        try {
            long t1 = System.currentTimeMillis();

            Map<String, String[]> requestParams = new HashMap<>(1);
            requestParams.put("userId",new String[]{String.valueOf(userId)});
            String sig = SignUtil.sign(secret, requestParams);
            resultVO = userFriendClient.userFriendsList(userId);
            long t2 = System.currentTimeMillis();
            log.info("查询道友列表cost:{}ms，sig={},userId={},resultVO={}",t2-t1,sig,userId, JSON.toJSONString(resultVO));
            if(resultVO==null || resultVO.getCode()==null || ResultStatus.SUCCESS.getCode()!=resultVO.getCode()){
                log.error("查询道友列表失败，cost:{}ms，sig={},userId={},resultVO={}",t2-t1,sig,userId, JSON.toJSONString(resultVO));
                throw new CheckRunException("查询道友列表失败：userId="+userId);
            }

            if(resultVO.getData() != null){
                list = JSON.parseArray(JSON.toJSONString(resultVO.getData()),UserFriendVO.class);
            }
        } catch (Exception e) {
            log.error("查询道友列表失败，userId={},resultVO={},e={}",userId, JSON.toJSONString(resultVO),e);
        }
        return list;
    }

    /**
     * 查询用户道友黑名单列表
     * @param userId
     * @return
     */
    public List<UserBlackVO> userBlackList(Long userId){
        ResultVO resultVO =null;
        List<UserBlackVO> list = Lists.newArrayList();
        try {
            long t1 = System.currentTimeMillis();

            Map<String, String[]> requestParams = new HashMap<>(1);
            requestParams.put("userId",new String[]{String.valueOf(userId)});
            String sig = SignUtil.sign(secret, requestParams);
            resultVO = userFriendClient.myBlacklist(sig,userId);
            long t2 = System.currentTimeMillis();
            log.info("查询用户道友黑名单cost:{}ms，sig={},userId={},resultVO={}",t2-t1,sig,userId, JSON.toJSONString(resultVO));
            if(resultVO==null || resultVO.getCode()==null || ResultStatus.SUCCESS.getCode()!=resultVO.getCode()){
                log.error("查询用户道友黑名单失败，cost:{}ms，sig={},userId={},resultVO={}",t2-t1,sig,userId, JSON.toJSONString(resultVO));
                throw new CheckRunException("查询用户道友黑名单失败：userId="+userId);
            }

            if(resultVO.getData() != null){
                list = JSON.parseArray(JSON.toJSONString(resultVO.getData()),UserBlackVO.class);
            }
        } catch (Exception e) {
            log.error("查询用户道友黑名单失败，userId={},resultVO={},e={}",userId, JSON.toJSONString(resultVO),e);
        }
        return list;
    }

//    @Async("taskExecutor")
    public void addUserLearnTime(LearnTimeParamVO learnTimeParamVO ,boolean start){
        ResultVO resultVO =null;
        try {
            String statusMsg = start?"开始学习":"结束学习";

            long t1 = System.currentTimeMillis();

            Map<String, String[]> requestParams = new HashMap<>(1);
            String sig = SignUtil.sign(secret, requestParams);
            traceLoger.info("addUserLearnTime 用户【{}】{}，修改用户状态，参数: {}",learnTimeParamVO.getUserId(),statusMsg,JSON.toJSONString(learnTimeParamVO));
            resultVO = userClient.addUserLearnTime(learnTimeParamVO);
            long t2 = System.currentTimeMillis();
            traceLoger.info("addUserLearnTime 用户【{}】{}，修改用户状态耗时{}，结果: {}",learnTimeParamVO.getUserId(),statusMsg,t2-t1,JSON.toJSONString(resultVO));
            log.info("添加学习时长cost:{}ms，sig={},learnTimeParamVO={},resultVO={}",t2-t1,sig,JSON.toJSONString(learnTimeParamVO), JSON.toJSONString(resultVO));
            if(resultVO==null || resultVO.getCode()==null || ResultStatus.SUCCESS.getCode()!=resultVO.getCode()){
                log.error("添加学习时长失败，cost:{}ms，sig={},learnTimeParamVO={},resultVO={}",t2-t1,sig,JSON.toJSONString(learnTimeParamVO), JSON.toJSONString(resultVO));
                throw new CheckRunException("添加学习时长失败!");
            }

        } catch (Exception e) {
            log.error("添加学习时长失败，learnTimeParamVO={},resultVO={},e={}",JSON.toJSONString(learnTimeParamVO), JSON.toJSONString(resultVO),e);
        }
    }

//    @Async("taskExecutor")
    public void updateUserInfo(Long userId){
        ResultVO resultVO =null;
        try {
            long t1 = System.currentTimeMillis();

            Map<String, String[]> requestParams = new HashMap<>(1);
            String sig = SignUtil.sign(secret, requestParams);

            UserParamVO userParamVO = new UserParamVO();
            userParamVO.setId(userId);
            userParamVO.setStatus(3);

            resultVO = userClient.updateUserInfo(userId,userParamVO);
            long t2 = System.currentTimeMillis();
            log.info("修改用户连麦学习状态，cost:{}ms，sig={},userParamVO={},resultVO={}",t2-t1,sig,JSON.toJSONString(userParamVO), JSON.toJSONString(resultVO));
            if(resultVO==null || resultVO.getCode()==null || ResultStatus.SUCCESS.getCode()!=resultVO.getCode()){
                log.error("修改用户连麦学习状态失败，cost:{}ms，sig={},userParamVO={},resultVO={}",t2-t1,sig,JSON.toJSONString(userParamVO), JSON.toJSONString(resultVO));
                throw new CheckRunException("修改用户连麦学习状态失败!");
            }

        } catch (Exception e) {
            log.error("修改用户连麦学习状态失败，userId={},resultVO={},e={}",userId, JSON.toJSONString(resultVO),e);
        }
    }

    @Cacheable(cacheNames = USER_TOTAL_LIVE_TIME, key = "#userId")
    public Integer totalLiveTime(Long userId){
        return userClient.totalLiveMinute(userId).getData();
    }

}
